package worst.shopping.lists;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import database.DataBaseKeys;
import database.ListDAO;
import database.ProductDAO;
import worst.shopping.R;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.text.InputType;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;

import android.widget.ListView;

public class EditListActivity extends ListActivity {
	private ProductDAO _productDAO;
	private Cursor _productCursor;
	private EditListHighlightableImageCursorAdapter _adapter;
	
	private EditText _listName;
	private ListDAO _listDAO;

	private class MapContainer
	{
		
		public Map< Integer, Integer > _itemsToAdd;
		public Map< Integer, Integer > _itemsToRemove;
		public Map< Integer, Integer > _itemsToUpdate;
		public Set< Entry< Integer, Integer >> _selectedItems;
		
		public MapContainer()
		{
			_itemsToAdd = new HashMap<Integer, Integer>();
			_itemsToRemove = new HashMap<Integer, Integer>();
			_itemsToUpdate = new HashMap<Integer, Integer>();
		}
	}
	
	MapContainer _mapContainer;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setContentView(R.layout.managelistactivity_layout);

		_listName = (EditText)this.findViewById(R.id.createlistactivity_listname_edittext);
		_listName.setText(getIntent().getExtras().getString(DataBaseKeys.LIST_NAME));
		_productDAO = new ProductDAO(getApplication());
		_listDAO = new ListDAO(getApplication());
		_productCursor = _productDAO.getAllProductsCursor();

		startManagingCursor(_productCursor);
		
		setUpListView();	
		
		final EditText listNameEditText = _listName;
		
		listNameEditText.setOnEditorActionListener(new OnEditorActionListener() {

	        public boolean onEditorAction(TextView v, int actionId,
	                KeyEvent event) {
	            if (event != null&& (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) {
	                InputMethodManager in = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
	                in.hideSoftInputFromWindow(listNameEditText
	                        .getApplicationWindowToken(),
	                        InputMethodManager.HIDE_NOT_ALWAYS);
	            }
	            return false;
	        }
	    });		
	}

	private void setUpListView() {
		ListView listView = getListView();
		
		_adapter = new EditListHighlightableImageCursorAdapter
				(this, 
				R.layout.listitem_withextra, _productCursor, 
				new String[] { DataBaseKeys.PRODUCT_NAME, DataBaseKeys.PRODUCT_ICON }, 
				new int[]{ R.id.list_item_name, R.id.list_item_image}, 
				getResources().getDrawable(R.drawable.gradient));

		listView.setAdapter(_adapter);
		listView.setOnItemClickListener(new OnItemClickListener() {

			public void onItemClick(AdapterView<?> adapterview, View view, int pos,
					long id) {
				final int index = pos;
				 
				AlertDialog.Builder builder = new AlertDialog.Builder(EditListActivity.this);
				final EditText countEditText = new EditText(EditListActivity.this);
				builder.setView(countEditText);
				builder.setMessage("Amount")
				       .setCancelable(true);
				
				countEditText.setInputType(InputType.TYPE_CLASS_NUMBER);
				//if item is already selected
				//let user choose to change the count or remove the selection
				if(_adapter.isSelected(pos))
				{
					countEditText.setText(""+_adapter.getCountForSelectedItem(index));
					builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
					           public void onClick(DialogInterface dialog, int id) {
					        	   Integer count = Integer.parseInt(countEditText.getText().toString());
					        	   _adapter.selectItem(index, count);
					        	   _mapContainer._itemsToUpdate.put(index, count);;
					        	   _adapter.notifyDataSetChanged();
					           }
					       })
					       .setNegativeButton("Remove", new DialogInterface.OnClickListener() {
					           public void onClick(DialogInterface dialog, int id){		
					                _adapter.unselectItem(index);
					                _mapContainer._itemsToUpdate.remove(index);
					                _mapContainer._itemsToRemove.put(index, 0);
					                _adapter.notifyDataSetChanged();	
					           }
					       });
				}
				else
				{
					countEditText.setText("1");
					builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
					           public void onClick(DialogInterface dialog, int id) {
					        	   	Integer count = Integer.parseInt(countEditText.getText().toString());
					        	   _adapter.selectItem(index, count);
					        	   _mapContainer._itemsToAdd.put(index, count);
					        	   _mapContainer._itemsToRemove.remove(index);					        	   
					        	   _adapter.notifyDataSetChanged();
					           }
					       })
					       .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
					           public void onClick(DialogInterface dialog, int id) {
					                dialog.cancel();
					           }
					       });
				}
				
				builder.create().show();
			}
		});	

		_mapContainer = (MapContainer) getLastNonConfigurationInstance();
		if(_mapContainer != null)
		{
			_adapter.setSelectedItemsEntrySet(_mapContainer._selectedItems);
		}	
		else
		{
			_mapContainer = new MapContainer();
		}
		
		Cursor cursor = _listDAO.getItemsForList(_listName.getText().toString());

		if(cursor.moveToFirst())
		{
			do
			{
				String currentProductName = cursor.getString(cursor.getColumnIndex(DataBaseKeys.PRODUCT_NAME));
				if(_productCursor.moveToFirst())
				{
					do
					{
						String name = _productCursor.getString(_productCursor.getColumnIndex(DataBaseKeys.PRODUCT_NAME));
						if(name.equals(currentProductName))
						{
							_adapter.selectItem(_productCursor.getPosition(), cursor.getInt(cursor.getColumnIndex(DataBaseKeys.PRODUCT_COUNT)));
						}
					}while(_productCursor.moveToNext());
				}
			}while(cursor.moveToNext());
		}
		
		
	}
	
	private void showListAlreadyExistsError(String listname) {
		AlertDialog.Builder builder = new AlertDialog.Builder(EditListActivity.this);
		builder.setTitle("Sorry!");
		builder.setMessage("Listname " + listname +" already taken");
		builder.setCancelable(false);
		builder.setNeutralButton("Ok", null);
		builder.create().show();
	}	
	
	public void saveButtonClicked(View view)
	{
		//check if the new list name is not already taken
		String inputListName = getIntent().getExtras().getString(DataBaseKeys.LIST_NAME);
		String currentListName = _listName.getText().toString();
		
		if(!inputListName.equals(currentListName))
		{
			if(_listDAO.listExists(currentListName))
			{
				showListAlreadyExistsError(currentListName);
				return;
			}
			else
			{
				//rename list
				_listDAO.renameList(inputListName, currentListName);				
			}
		}

		//execute changes
		
		_listDAO.beginTransaction();
		
		try {
			Set< Integer > itemsToRemove = _mapContainer._itemsToRemove.keySet();
			
			for (Integer integer : itemsToRemove) {
				_productCursor.moveToPosition(integer);
				_listDAO.removeListEntry(currentListName, _productCursor.getString(_productCursor.getColumnIndex(DataBaseKeys.PRODUCT_NAME)));
			}
			
			Set< Integer > itemsToAdd = _mapContainer._itemsToAdd.keySet();
			
			for (Integer integer : itemsToAdd) {
				_productCursor.moveToPosition(integer);
				_listDAO.insertListEntry(currentListName, _productCursor.getString(_productCursor.getColumnIndex(DataBaseKeys.PRODUCT_NAME)), _mapContainer._itemsToAdd.get(integer).toString());
			}
			
			Set< Integer > itemsToUpdate = _mapContainer._itemsToUpdate.keySet();
			
			for(Integer integer : itemsToUpdate)
			{
				_productCursor.moveToPosition(integer);
				_listDAO.updateListEntryCount(currentListName,  _productCursor.getString(_productCursor.getColumnIndex(DataBaseKeys.PRODUCT_NAME)), _mapContainer._itemsToUpdate.get(integer).toString());
			}		

		
			_listDAO.setTransactionSuccessful();
		} catch (Exception e) {
			// TODO: handle exception
		} finally {
			_listDAO.endTransaction();
		}
		
	    Intent result = new Intent();
	    result.putExtra(DataBaseKeys.LIST_NAME, currentListName);
	    setResult(Activity.RESULT_OK, result);		
	    
		finish();
	}
	
	public void cancelButtonClicked(View view)
	{
		finish();
	}
	
	@Override
	public Object onRetainNonConfigurationInstance() {
		_mapContainer._selectedItems = _adapter.getSelectedItemsEntrySet();
		
		return _mapContainer;
	}
}
